package io.plus.server;

import io.plus.common.io;
import io.plus.common.packet.metadata.Command;
import io.plus.common.packet.metadata.ResponseMessage;
import io.plus.common.protocol.Decoder;
import io.plus.common.protocol.Encoder;
import io.plus.common.protocol.Packet;
import io.plus.engine.pulse.AsynchronousSocketChannelContext;
import io.plus.engine.pulse.Configuration;
import io.plus.engine.pulse.DecodeException;
import io.plus.engine.pulse.PacketMetadata;
import io.plus.engine.server.ServerHandler;
import io.plus.server.command.CommandHandler;
import io.plus.server.command.CommandManager;
import lombok.Data;

import java.nio.ByteBuffer;

@Data
public class ServerHandlerImpl implements ServerHandler {

    private UserConfiguration userConfiguration;

    public ServerHandlerImpl(UserConfiguration userConfiguration) {
        this.userConfiguration = userConfiguration;
    }

    @Override
    public PacketMetadata decode(AsynchronousSocketChannelContext asynchronousSocketChannelContext, ByteBuffer byteBuffer, int limit, int position, int readableLength) throws DecodeException {

        PacketMetadata packetMetadata = Decoder.decode(asynchronousSocketChannelContext, byteBuffer);
        return packetMetadata;
    }

    @Override
    public ByteBuffer encode(Configuration configuration, AsynchronousSocketChannelContext asynchronousSocketChannelContext, PacketMetadata packetMetadata) {
        Packet packet1 = (Packet) packetMetadata;
        return Encoder.encode(configuration, asynchronousSocketChannelContext, packet1);
    }


    @Override
    public void handler(AsynchronousSocketChannelContext asynchronousSocketChannelContext, PacketMetadata packetMetadata) throws Exception {

        Packet tcpPacket = (Packet) packetMetadata;
        CommandHandler commandHandler = CommandManager.getCommandHandler(tcpPacket.getCommand());
        if (commandHandler == null) {
            Packet packet1 = new Packet(Command.unknow, Status.ok, new ResponseMessage(Command.unknow, Status.C10017).toByte());
            io.send(asynchronousSocketChannelContext, packet1);
            return;
        }
        Packet response = commandHandler.handler(userConfiguration, asynchronousSocketChannelContext, tcpPacket);
        if (response != null && tcpPacket.getSynchronismSerialNumber() < 1) {
            io.send(asynchronousSocketChannelContext, response);
        }
    }


}
